home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / lapbtime.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  3KB  |  161 lines

  1. /* LAPB (AX.25) timer recovery routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by G1EMM
  5.  */
  6. #include "global.h"
  7. #include "config.h"
  8. #ifdef AX25
  9. #include "mbuf.h"
  10. #include "ax25.h"
  11. #include "timer.h"
  12. #include "lapb.h"
  13.  
  14. static void tx_enq __ARGS((struct ax25_cb *axp));
  15.  
  16. int lapbtimertype = 0;        /* default to binary exponential */
  17.  
  18. /* Called whenever timer T1 expires */
  19. void
  20. recover(p)
  21. void *p;
  22. {
  23.     register struct ax25_cb *axp = (struct ax25_cb *)p;
  24.  
  25.     axp->flags.retrans = 1;
  26.     axp->retries++;
  27.  
  28.     switch(lapbtimertype){
  29.         case 2:             /* original backoff mode*/
  30.             set_timer(&axp->t1,axp->srt * 2);
  31.             break;
  32.         case 1:             /* linear backoff mode */
  33.             if((1L << axp->retries) < Blimit)
  34.                 set_timer(&axp->t1,dur_timer(&axp->t1) + axp->srt);
  35.             break;
  36.         case 0:             /* exponential backoff mode */
  37.             if((1L << axp->retries) < Blimit)
  38.                 set_timer(&axp->t1,dur_timer(&axp->t1)*2);
  39.             break;
  40.     }
  41.  
  42.  
  43.     switch(axp->state){
  44.     case LAPB_SETUP:
  45.         if(axp->n2 != 0 && axp->retries > axp->n2){
  46. #ifdef NETROM
  47.             nr_derate(axp);
  48. #endif
  49.             free_q(&axp->txq);
  50.             axp->reason = LB_TIMEOUT;
  51.             lapbstate(axp,LAPB_DISCONNECTED);
  52.         } else {
  53.             sendctl(axp,LAPB_COMMAND,SABM|PF);
  54.             start_timer(&axp->t1);
  55.         }
  56.         break;
  57.     case LAPB_DISCPENDING:
  58.         if(axp->n2 != 0 && axp->retries > axp->n2){
  59. #ifdef NETROM
  60.             nr_derate(axp);
  61. #endif
  62.             axp->reason = LB_TIMEOUT;
  63.             lapbstate(axp,LAPB_DISCONNECTED);
  64.         } else {
  65.             sendctl(axp,LAPB_COMMAND,DISC|PF);
  66.             start_timer(&axp->t1);
  67.         }
  68.         break;
  69.     case LAPB_CONNECTED:
  70.     case LAPB_RECOVERY:
  71.         if(axp->n2 != 0 && axp->retries > axp->n2){
  72.             /* Give up */
  73. #ifdef NETROM
  74.             nr_derate(axp);
  75. #endif
  76.             sendctl(axp,LAPB_RESPONSE,DM|PF);
  77.             free_q(&axp->txq);
  78.             axp->reason = LB_TIMEOUT;
  79.             lapbstate(axp,LAPB_DISCONNECTED);
  80.         } else {
  81.             /* Transmit poll */
  82.             tx_enq(axp);
  83.             lapbstate(axp,LAPB_RECOVERY);
  84.         }
  85.         break;
  86.     }
  87. }
  88.  
  89.  
  90. /* Send a poll (S-frame command with the poll bit set) */
  91. void
  92. pollthem(p)
  93. void *p;
  94. {
  95.     register struct ax25_cb *axp;
  96.  
  97.     axp = (struct ax25_cb *)p;
  98.     if(axp->proto == V1)
  99.         return;    /* Not supported in the old protocol */
  100.     switch(axp->state){
  101.     case LAPB_CONNECTED:
  102.         axp->retries = 0;
  103.         tx_enq(axp);
  104.         lapbstate(axp,LAPB_RECOVERY);
  105.         break;
  106.     }
  107. }
  108.  
  109. /* Called whenever timer T4 (link rudundancy timer) expires */
  110. void
  111. redundant(p)
  112. void *p;
  113. {
  114.     register struct ax25_cb *axp;
  115.  
  116.     axp = (struct ax25_cb *)p;
  117.     switch(axp->state){
  118.     case LAPB_CONNECTED:
  119.     case LAPB_RECOVERY:
  120.         axp->retries = 0;
  121.         sendctl(axp,LAPB_COMMAND,DISC|PF);
  122.         start_timer(&axp->t1);
  123.         free_q(&axp->txq);
  124.         lapbstate(axp,LAPB_DISCPENDING);
  125.         break;
  126.     }
  127. }
  128.  
  129. /* Transmit query */
  130. static void
  131. tx_enq(axp)
  132. register struct ax25_cb *axp;
  133. {
  134.     char ctl;
  135.     struct mbuf *bp;
  136.  
  137.     /* I believe that retransmitting the oldest unacked
  138.      * I-frame tends to give better performance than polling,
  139.      * as long as the frame isn't too "large", because
  140.      * chances are that the I frame got lost anyway.
  141.      * This is an option in LAPB, but not in the official AX.25.
  142.      */
  143.     if(axp->txq != NULLBUF
  144.      && (len_p(axp->txq) < axp->pthresh || axp->proto == V1)){
  145.         /* Retransmit oldest unacked I-frame */
  146.         dup_p(&bp,axp->txq,0,len_p(axp->txq));
  147.         ctl = PF | I | (((axp->vs - axp->unack) & MMASK) << 1)
  148.          | (axp->vr << 5);
  149.         sendframe(axp,LAPB_COMMAND,ctl,bp);
  150.     } else {
  151.         ctl = len_p(axp->rxq) >= axp->window ? RNR|PF : RR|PF;    
  152.         sendctl(axp,LAPB_COMMAND,ctl);
  153.     }
  154.     axp->response = 0;    
  155.     stop_timer(&axp->t3);
  156.     start_timer(&axp->t1);
  157. }
  158.  
  159. #endif /* AX25 */
  160.  
  161.